跳到主要内容

随机梯度下降

随机梯度下降

随机梯度下降(Stochastic Gradient Descent,简称SGD)是一种用于训练机器学习模型的优化算法。它是梯度下降算法的一种变体,主要用于大规模数据集和高维特征空间中的模型训练。与传统梯度下降不同,SGD使用随机抽样的小批量数据来估计梯度,从而减少计算开销,但引入了一些随机性。

下面是随机梯度下降的工作原理和一个具体的示例:

工作原理

  1. 随机梯度下降首先随机选择一个小批量(通常是一小部分)训练样本。
  2. 使用这个小批量数据来计算损失函数关于模型参数的梯度(即损失函数对参数的导数)的估计值。这个梯度估计通常只是整个训练集的梯度的近似。
  3. 使用梯度的估计值来更新模型参数,以减小损失函数的值。
  4. 重复上述步骤,每次迭代都随机选择不同的小批量数据,直到满足停止条件(例如达到最大迭代次数或收敛到足够小的损失值)。

示例: 假设我们要使用随机梯度下降来训练一个线性回归模型,目标是找到最佳的权重 w\mathbf{w} 和截距 bb,以拟合一个包含大量数据点的数据集。

  1. 初始化权重 w\mathbf{w} 和截距 bb 的值。
  2. 随机选择一个小批量数据,例如选择一小部分数据点。
  3. 计算这个小批量数据上的平均损失关于 w\mathbf{w}bb 的梯度。
  4. 使用梯度的估计值来更新权重和截距,例如按照以下规则更新:
    • wwα梯度w\mathbf{w} \leftarrow \mathbf{w} - \alpha \cdot \text{梯度}_w
    • bbα梯度bb \leftarrow b - \alpha \cdot \text{梯度}_b 其中,α\alpha 是学习率,控制了更新步长的大小。
  5. 重复上述步骤,不断选择新的小批量数据并更新参数,直到满足停止条件。

随机梯度下降的主要优势在于它的计算效率,特别是在大规模数据集上。它的随机性可以帮助算法跳出局部极小值,并且通常不需要计算整个训练集的梯度,因此更快。但它也可能会引入一些噪声,导致训练过程中损失函数的震荡。为了解决这个问题,可以使用学习率调度策略或采用其他随机梯度下降的变体。

使用数学公式来表达

当使用随机梯度下降(Stochastic Gradient Descent,SGD)来更新模型参数时,可以使用以下数学公式来表示更新过程:

假设我们要最小化损失函数 LL,其中 θ\theta 表示模型参数(可能包括权重和截距),L(θ)\nabla L(\theta) 表示损失函数关于参数的梯度。

SGD的参数更新过程如下:

  1. 随机选择一个小批量数据(通常用 BB 表示),这个小批量包含 mm 个样本。

  2. 计算损失函数在这个小批量数据上的平均梯度估计(即损失函数对参数的导数的估计值):L(θ;B)=1mi=1mL(θ;(xi,yi))\nabla L(\theta; B) = \frac{1}{m} \sum_{i=1}^{m} \nabla L(\theta; (x_i, y_i)) 这里,(xi,yi)(x_i, y_i) 表示小批量数据中的第 ii 个样本。

  3. 使用梯度估计值来更新参数,通常按照以下规则: θθαL(θ;B)\theta \leftarrow \theta - \alpha \cdot \nabla L(\theta; B) 其中,α\alpha 是学习率(learning rate),控制了更新步长的大小。

  4. 重复上述步骤,不断选择新的小批量数据并更新参数,直到满足停止条件(例如达到最大迭代次数或收敛到足够小的损失值)。

这个更新过程中,L(θ;B)\nabla L(\theta; B) 表示在当前小批量数据 BB 上损失函数关于参数 θ\theta 的梯度估计。通过不断迭代,模型的参数逐渐调整,以最小化损失函数,从而拟合数据。

需要注意的是,SGD的随机性体现在每次迭代中选择不同的小批量数据,这有助于跳出局部极小值,并且可以在大规模数据集上提高计算效率。学习率 α\alpha 的选择很重要,它影响了参数更新的步长,通常需要进行调整以确保算法的收敛性和性能。

提示

数学符号 \nabla 表示了向量微分算子(Vector Differential Operator),通常称为“nabla”或“德尔符号”。它在数学、物理和工程领域中广泛用于描述矢量和标量函数的梯度、散度和旋度等运算。具体来说,\nabla 可以表示为一个矢量,其分量表示了函数在不同方向上的偏导数。

梯度是 \nabla 的常见应用,用于描述标量函数的变化率和方向。对于标量函数 f(x)f(\mathbf{x}),其梯度表示为 f(x)\nabla f(\mathbf{x}),是一个矢量,其中每个分量是函数在相应坐标方向上的偏导数。

例如,如果 f(x)f(\mathbf{x}) 是一个二维函数,梯度 f(x)\nabla f(\mathbf{x}) 表示为 (fx,fy)(\frac{\partial f}{\partial x}, \frac{\partial f}{\partial y}),其中 fx\frac{\partial f}{\partial x} 表示函数在 xx 方向上的变化率,fy\frac{\partial f}{\partial y} 表示函数在 yy 方向上的变化率。

PyTorch 中使用 SGD

随机梯度下降(SGD)是一种优化算法,用于最小化损失函数。与传统的梯度下降方法不同,SGD每次只使用一个训练样本来计算梯度并更新模型参数。这使得SGD在大数据集上更为高效。

以下是如何在PyTorch中使用SGD的具体例子:

1. 线性回归与SGD

我们首先使用一个简单的线性回归任务来展示SGD的使用。

import torch
import torch.nn as nn
import torch.optim as optim

# 生成模拟数据
torch.manual_seed(42)
x = torch.linspace(-1, 1, 1000).view(1000, 1)
y = 2 * x + torch.randn(x.size()) * 0.3

# 定义线性回归模型
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(1, 1)

def forward(self, x):
return self.linear(x)

# 实例化模型
model = LinearRegression()

# 定义损失函数
criterion = nn.MSELoss()

# 使用SGD优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
for i in range(len(x)):
optimizer.zero_grad()
outputs = model(x[i])
loss = criterion(outputs, y[i])
loss.backward()
optimizer.step()
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

在上述代码中,我们使用了SGD优化器来训练线性回归模型。注意,我们在每个epoch中都遍历了整个数据集,每次只使用一个样本来计算梯度并更新模型参数。

2. 使用SGD的变种

PyTorch还提供了SGD的几种变种,如Momentum和Nesterov Momentum。这些变种在更新规则上有所不同,但它们的基本思想都是基于SGD的。

例如,要使用带有Momentum的SGD,你可以这样做:

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

Momentum有助于加速SGD在相关方向上的收敛速度,并抑制震荡。

总的来说,SGD及其变种是训练深度学习模型的常用优化算法。在PyTorch中使用它们非常简单,只需选择适当的优化器并设置相关参数即可。

SGD 的内部实现

以下是 SGD 的伪代码实现:

def SGD(f, df, x0, learning_rate, num_iterations):
w = x0
for i in range(num_iterations):
sample = randomly_select_one_sample()
gradient = df(w, sample)
w = w - learning_rate * gradient
return w